package com.nbcio.im.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nbcio.common.core.domain.R;
import com.nbcio.common.core.utils.StringUtils;
import com.nbcio.im.config.ImProperties;
import com.nbcio.im.core.ImMessage;
import com.nbcio.im.core.ImGroup;
import com.nbcio.im.core.ImGroupMember;
import com.nbcio.system.domain.vo.SysUserVo;
import com.nbcio.im.core.service.ImMessageService;
import com.nbcio.im.core.service.ImUserService;
import com.nbcio.im.core.service.ImGroupService;
import com.nbcio.im.core.service.ImGroupMemberService;
import com.nbcio.im.service.ImService;
import com.nbcio.system.service.CommonService;
import com.alibaba.fastjson.JSONObject;
import com.nbcio.system.domain.SysUser;
import com.nbcio.common.websocket.websocket.WebSocketServer;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * IM服务实现类
 *
 * @author nbacheng
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ImServiceImpl implements ImService {

    private final ImProperties imProperties;
    private final ImMessageService imMessageService;
    private final ImUserService imUserService;
    private final ImGroupService imGroupService;
    private final ImGroupMemberService imGroupMemberService;
    
    @Resource
    private CommonService commonService;
    @Resource
    private WebSocketServer webSocketServer;
    private final ObjectMapper objectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, Object>> loginToIm(SysUser user) {
        try {
            if (!imProperties.isEnabled()) {
                log.warn("IM功能未启用");
                return R.fail("IM功能未启用");
            }

            // 获取系统用户信息
            SysUserVo sysUserVo = imUserService.getSysUser(user.getUserId());
            if (sysUserVo == null) {
                return R.fail("用户不存在");
            }
            
            // 更新用户在线状态
            imUserService.updateUserStatus(user.getUserId(), "online");
            
            // 构建返回数据
            Map<String, Object> result = new HashMap<>();
            result.put("userId", sysUserVo.getUserId());
            result.put("username", sysUserVo.getUserName());
            result.put("nickname", sysUserVo.getNickName());
            result.put("avatar", sysUserVo.getAvatar());
            result.put("status", sysUserVo.getImStatus());
            result.put("lastOnlineTime", sysUserVo.getImLastOnlineTime());
            
            log.info("用户登录IM系统成功: {} ({})", user.getUserId(), user.getUserName());
            return R.ok(result);
        } catch (Exception e) {
            log.error("用户登录IM系统失败: {}", e.getMessage(), e);
            return R.fail("登录IM系统失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> logoutFromIm(Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.ok();
            }

            // 更新用户离线状态
            imUserService.updateUserStatus(userId, "offline");
            
            log.info("用户登出IM系统成功: {}", userId);
            return R.ok();
        } catch (Exception e) {
            log.error("用户登出IM系统失败: {}", e.getMessage(), e);
            return R.fail("登出IM系统失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> syncUserToIm(SysUser user) {
        try {
            if (!imProperties.isEnabled()) {
                return R.ok();
            }

            // 直接使用系统用户，无需同步
            log.info("用户已集成到IM系统: {}", user.getUserName());
            return R.ok();
        } catch (Exception e) {
            log.error("用户同步到IM系统失败: {}", e.getMessage(), e);
            return R.fail("同步用户失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> batchSyncUsersToIm(List<SysUser> users) {
        try {
            if (!imProperties.isEnabled()) {
                return R.ok();
            }

            // 直接使用系统用户，无需批量同步
            log.info("批量用户已集成到IM系统，数量: {}", users.size());
            return R.ok();
        } catch (Exception e) {
            log.error("批量同步用户到IM系统失败: {}", e.getMessage(), e);
            return R.fail("批量同步用户失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> sendMessage(Long fromUserId, Long toUserId, String content, String messageType) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 发送私聊消息
            String messageId = imMessageService.sendPrivateMessage(fromUserId, toUserId, content, messageType);
            
            // 获取消息和用户信息
            ImMessage message = imMessageService.getById(messageId);
            if (message != null) {
                // 获取发送者和接收者信息
                SysUserVo fromUser = imUserService.getSysUser(fromUserId);
                SysUserVo toUser = imUserService.getSysUser(toUserId);
                
                if (fromUser != null && toUser != null) {
                    // 构造IM格式的WebSocket消息
                    JSONObject imMessage = new JSONObject();
                    imMessage.put("type", "new_message");
                    imMessage.put("messageId", message.getMessageId());
                    imMessage.put("fromUserId", message.getFromUserId());
                    imMessage.put("toUserId", message.getToUserId());
                    imMessage.put("content", message.getContent());
                    imMessage.put("messageType", message.getMessageType());
                    imMessage.put("createTime", message.getCreateTime());
                    imMessage.put("senderName", fromUser.getNickName() != null ? fromUser.getNickName() : fromUser.getUserName());
                    imMessage.put("senderAvatar", fromUser.getAvatar());
                    
                    // 直接通过WebSocket发送IM消息
                    webSocketServer.pushMessage(toUser.getUserName(), imMessage.toJSONString());
                } else {
                    log.warn("发送者或接收者用户不存在，无法发送消息: fromUser={}, toUser={}", fromUser, toUser);
                }
            }
            
            log.info("发送私聊消息成功: {} -> {}, 消息ID: {}", fromUserId, toUserId, messageId);
            return R.ok();
        } catch (Exception e) {
            log.error("发送消息失败: {}", e.getMessage(), e);
            return R.fail("发送消息失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> sendGroupMessage(Long fromUserId, String groupId, String content, String messageType) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 发送群组消息
            String messageId = imMessageService.sendGroupMessage(fromUserId, groupId, content, messageType);
            
            // 通过WebSocket发送给群组所有成员
            ImMessage message = imMessageService.getById(messageId);
            if (message != null) {
                // 获取群组所有成员
                List<ImGroupMember> members = imGroupService.getGroupMembers(groupId);
                if (members != null && !members.isEmpty()) {
                    // 获取发送者信息
                    SysUserVo fromUser = imUserService.getSysUser(fromUserId);
                    
                    // 构造群聊消息格式
                    JSONObject groupMessage = new JSONObject();
                    groupMessage.put("type", "new_group_message");
                    groupMessage.put("messageId", message.getMessageId());
                    groupMessage.put("fromUserId", message.getFromUserId());
                    groupMessage.put("groupId", message.getGroupId());
                    groupMessage.put("content", message.getContent());
                    groupMessage.put("messageType", message.getMessageType());
                    groupMessage.put("createTime", message.getCreateTime());
                    groupMessage.put("senderName", fromUser != null ? fromUser.getNickName() : "未知用户");
                    groupMessage.put("senderAvatar", fromUser != null ? fromUser.getAvatar() : "");
                    
                    // 发送给群组所有成员
                    for (ImGroupMember member : members) {
                        if (!member.getUserId().equals(fromUserId)) { // 不发送给发送者自己
                            SysUserVo memberUser = imUserService.getSysUser(member.getUserId());
                            if (memberUser != null) {
                                webSocketServer.pushMessage(memberUser.getUserName(), groupMessage.toJSONString());
                            } else {
                                log.warn("用户信息不存在，无法发送消息: userId={}", member.getUserId());
                            }
                        }
                    }
                } else {
                    log.warn("群组没有成员，无法发送消息: 群组ID={}", groupId);
                }
            }

            log.info("发送群组消息成功: {} -> {}, 消息ID: {}", fromUserId, groupId, messageId);
            return R.ok();
        } catch (Exception e) {
            log.error("发送群组消息失败: {}", e.getMessage(), e);
            return R.fail("发送群组消息失败: " + e.getMessage());
        }
    }


    /**
     * 发送群聊通知
     *
     * @param groupId 群组ID
     * @param notificationType 通知类型
     * @param content 通知内容
     * @param operatorId 操作者ID
     */
    private void sendGroupNotification(String groupId, String notificationType, String content, Long operatorId) {
        try {
            // 获取群组所有成员
            List<ImGroupMember> members = imGroupService.getGroupMembers(groupId);
            if (members != null && !members.isEmpty()) {
                // 获取操作者信息
                SysUserVo operator = imUserService.getSysUser(operatorId);
                
                // 构造通知消息
                JSONObject notification = new JSONObject();
                notification.put("type", "group_notification");
                notification.put("notificationType", notificationType);
                notification.put("groupId", groupId);
                notification.put("content", content);
                notification.put("operatorId", operatorId);
                notification.put("operatorName", operator != null ? operator.getNickName() : "未知用户");
                notification.put("createTime", LocalDateTime.now());
                
                // 发送给群组所有成员
                for (ImGroupMember member : members) {
                    SysUserVo memberUser = imUserService.getSysUser(member.getUserId());
                    if (memberUser != null) {
                        webSocketServer.pushMessage(memberUser.getUserName(), notification.toJSONString());
                        log.debug("发送群聊通知给用户: {}, 通知: {}", memberUser.getUserName(), notification.toJSONString());
                    }
                }
                
                log.info("群聊通知发送完成: 群组ID={}, 通知类型={}, 成员数={}", groupId, notificationType, members.size());
            }
        } catch (Exception e) {
            log.error("发送群聊通知失败: {}", e.getMessage(), e);
        }
    }

    @Override
    public R<Map<String, Object>> getUserImInfo(Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            SysUserVo sysUserVo = imUserService.getSysUser(userId);
            if (sysUserVo == null) {
                return R.fail("用户不存在");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("userId", sysUserVo.getUserId());
            result.put("username", sysUserVo.getUserName());
            result.put("nickname", sysUserVo.getNickName());
            result.put("avatar", sysUserVo.getAvatar());
            result.put("email", sysUserVo.getEmail());
            result.put("phone", sysUserVo.getPhonenumber());
            result.put("imStatus", sysUserVo.getImStatus());
            result.put("imLastOnlineTime", sysUserVo.getImLastOnlineTime());
            result.put("imSignature", sysUserVo.getImSignature());
            result.put("imGender", sysUserVo.getImGender());
            result.put("imRegion", sysUserVo.getImRegion());

            return R.ok(result);
        } catch (Exception e) {
            log.error("获取用户IM信息失败: {}", e.getMessage(), e);
            return R.fail("获取用户IM信息失败: " + e.getMessage());
        }
    }



    @Override
    public R<Map<String, Object>> getMessageHistory(Long userId, String targetId, Integer pageNum, Integer pageSize) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            log.info("获取消息历史: userId={}, targetId={}, pageNum={}, pageSize={}", 
                    userId, targetId, pageNum, pageSize);

            List<ImMessage> messages;
            final SysUserVo currentUser = imUserService.getSysUser(userId);
            final SysUserVo targetUser;
            
            // 判断是私聊还是群聊
            if (targetId.startsWith("group_")) {
                // 群聊消息历史
                String groupId = targetId;
                log.info("获取群聊消息历史: groupId={}", groupId);
                messages = imMessageService.getGroupMessageHistory(groupId, pageNum, pageSize);
                targetUser = null;
            } else {
                // 私聊消息历史
                Long targetUserId;
                if (targetId.startsWith("private_")) {
                    // 处理 private_xxx 格式的ID
                    targetUserId = Long.valueOf(targetId.substring(8));
                } else {
                    // 处理纯数字ID
                    targetUserId = Long.valueOf(targetId);
                }
                messages = imMessageService.getPrivateMessageHistory(userId, targetUserId, pageNum, pageSize);
                targetUser = imUserService.getSysUser(targetUserId);
            }
            
            // 转换消息格式
            List<Map<String, Object>> messageList = messages.stream().map(msg -> {
                Map<String, Object> messageMap = new HashMap<>();
                messageMap.put("messageId", msg.getMessageId());
                messageMap.put("fromUserId", msg.getFromUserId());
                messageMap.put("toUserId", msg.getToUserId());
                messageMap.put("content", msg.getContent());
                messageMap.put("messageType", msg.getMessageType());
                messageMap.put("createTime", msg.getCreateTime());
                messageMap.put("isRead", msg.getIsRead());
                messageMap.put("status", msg.getStatus());
                
                // 添加发送者信息
                if (msg.getFromUserId().equals(userId)) {
                    messageMap.put("senderName", currentUser != null ? currentUser.getNickName() : "我");
                    messageMap.put("senderAvatar", currentUser != null ? currentUser.getAvatar() : "");
                } else {
                    messageMap.put("senderName", targetUser != null ? targetUser.getNickName() : "对方");
                    messageMap.put("senderAvatar", targetUser != null ? targetUser.getAvatar() : "");
                }
                
                return messageMap;
            }).collect(Collectors.toList());

            Map<String, Object> result = new HashMap<>();
            result.put("records", messageList);
            result.put("list", messageList); // 兼容不同的前端格式
            result.put("total", messageList.size());
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            log.info("返回消息历史: {} 条消息", messageList.size());
            return R.ok(result);
        } catch (Exception e) {
            log.error("获取消息历史失败: {}", e.getMessage(), e);
            return R.fail("获取消息历史失败: " + e.getMessage());
        }
    }

    @Override
    public String getMessageId(Long fromUserId, Long toUserId, String content, String messageType) {
        try {
            // 查询最近发送的消息ID（放宽查询条件，只按发送者和时间查询）
            LambdaQueryWrapper<ImMessage> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImMessage::getFromUserId, fromUserId)
                   .eq(ImMessage::getToUserId, toUserId)
                   .eq(ImMessage::getTenantId, "000000")
                   .orderByDesc(ImMessage::getCreateTime)
                   .last("LIMIT 1");
            
            ImMessage message = imMessageService.getOne(wrapper);
            if (message != null) {
                log.debug("找到消息ID: {}", message.getMessageId());
                return message.getMessageId();
            } else {
                log.debug("未找到匹配的消息，fromUserId: {}, toUserId: {}", fromUserId, toUserId);
                return null;
            }
        } catch (Exception e) {
            log.error("获取消息ID失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 检查IM服务是否可用
     */
    private boolean isImServiceAvailable() {
        try {
            // 检查IM功能是否启用
            return imProperties.isEnabled();
        } catch (Exception e) {
            log.debug("IM服务健康检查失败: {}", e.getMessage());
            return false;
        }
    }

    // ==================== 群聊相关方法实现 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, Object>> createGroup(Long ownerId, String groupName, String description, String avatar, List<Long> memberIds) {
        try {
            log.info("创建群聊请求: ownerId={}, groupName={}, memberIds={}", ownerId, groupName, memberIds);
            log.info("IM配置状态: enabled={}", imProperties.isEnabled());
            
            if (!imProperties.isEnabled()) {
                log.warn("IM功能未启用，配置: {}", imProperties);
                return R.fail("IM功能未启用");
            }

            // 生成群ID
            String groupId = "group_" + System.currentTimeMillis() + "_" + ownerId;
            
            // 创建群组
            ImGroup group = new ImGroup();
            group.setGroupId(groupId);
            group.setGroupName(groupName);
            group.setDescription(description);
            group.setAvatar(avatar);
            group.setOwnerId(ownerId);
            group.setGroupType("normal");
            group.setMaxMembers(500);
            group.setMemberCount(1); // 群主算一个成员
            group.setStatus("active");
            group.setAllowInvite(1);
            group.setAllowMemberModify(0);
            group.setAllowMemberInvite(1);
            group.setTenantId("000000");
            
            // 保存群组
            boolean groupSaved = imGroupService.save(group);
            if (!groupSaved) {
                return R.fail("创建群组失败");
            }
            
            // 添加群主为成员
            ImGroupMember ownerMember = new ImGroupMember();
            ownerMember.setGroupId(groupId);
            ownerMember.setUserId(ownerId);
            ownerMember.setGroupNickname("");
            ownerMember.setRole("owner");
            ownerMember.setIsMuted(0);
            ownerMember.setEnabled(1);
            ownerMember.setTenantId("000000");
            
            boolean ownerSaved = imGroupMemberService.save(ownerMember);
            if (!ownerSaved) {
                return R.fail("添加群主失败");
            }
            
            // 添加其他成员
            int actualMemberCount = 1; // 群主算一个成员
            if (memberIds != null && !memberIds.isEmpty()) {
                for (Long memberId : memberIds) {
                    if (!memberId.equals(ownerId)) { // 避免重复添加群主
                        ImGroupMember member = new ImGroupMember();
                        member.setGroupId(groupId);
                        member.setUserId(memberId);
                        member.setGroupNickname("");
                        member.setRole("member");
                        member.setIsMuted(0);
                        member.setEnabled(1);
                        member.setTenantId("000000");
                        
                        boolean saved = imGroupMemberService.save(member);
                        if (saved) {
                            actualMemberCount++; // 每成功保存一个成员，计数+1
                        }
                    }
                }
                // 更新成员数量为实际保存的成员数
                group.setMemberCount(actualMemberCount);
                imGroupService.updateById(group);
            }
            
            // 返回群组信息
            Map<String, Object> result = new HashMap<>();
            result.put("groupId", groupId);
            result.put("groupName", groupName);
            result.put("description", description);
            result.put("avatar", avatar);
            result.put("ownerId", ownerId);
            result.put("memberCount", group.getMemberCount());
            
            log.info("创建群聊成功: groupId={}, groupName={}, ownerId={}", groupId, groupName, ownerId);
            return R.ok(result);
        } catch (Exception e) {
            log.error("创建群聊失败: {}", e.getMessage(), e);
            return R.fail("创建群聊失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<Map<String, Object>>> getUserGroups(Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 查询用户参与的群组
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getUserId, userId)
                   .eq(ImGroupMember::getEnabled, 1)
                   .eq(ImGroupMember::getTenantId, "000000");
            
            List<ImGroupMember> memberships = imGroupMemberService.list(wrapper);
            
            List<Map<String, Object>> groups = new ArrayList<>();
            for (ImGroupMember membership : memberships) {
                // 获取群组信息
                ImGroup group = imGroupService.getById(membership.getGroupId());
                if (group != null && "active".equals(group.getStatus())) {
                    Map<String, Object> groupInfo = new HashMap<>();
                    groupInfo.put("groupId", group.getGroupId());
                    groupInfo.put("groupName", group.getGroupName());
                    groupInfo.put("avatar", group.getAvatar());
                    groupInfo.put("description", group.getDescription());
                    groupInfo.put("memberCount", group.getMemberCount());
                    groupInfo.put("role", membership.getRole());
                    groupInfo.put("groupNickname", membership.getGroupNickname());
                    groups.add(groupInfo);
                }
            }
            
            log.info("获取用户群聊列表成功: userId={}, 群组数量={}", userId, groups.size());
            return R.ok(groups);
        } catch (Exception e) {
            log.error("获取用户群聊列表失败: {}", e.getMessage(), e);
            return R.fail("获取用户群聊列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<Map<String, Object>>> getConversationList(Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            List<Map<String, Object>> conversations = new ArrayList<>();
            
            // 获取私聊会话（基于消息历史）
            List<ImMessage> privateMessages = imMessageService.getPrivateConversations(userId);
            for (ImMessage message : privateMessages) {
                Long otherUserId = message.getFromUserId().equals(userId) ? message.getToUserId() : message.getFromUserId();
                SysUserVo otherUser = imUserService.getSysUser(otherUserId);
                
                if (otherUser != null) {
                    // 计算未读消息数
                    int unreadCount = imMessageService.getUnreadCount(userId, otherUserId, null);
                    
                    Map<String, Object> conversation = new HashMap<>();
                    conversation.put("id", "private_" + otherUserId);
                    conversation.put("name", otherUser.getNickName() != null ? otherUser.getNickName() : otherUser.getUserName());
                    conversation.put("avatar", otherUser.getAvatar());
                    conversation.put("lastMessage", message.getContent());
                    conversation.put("lastTime", message.getCreateTime());
                    conversation.put("unreadCount", unreadCount);
                    conversation.put("type", "private");
                    conversation.put("userId", otherUserId);
                    conversation.put("status", "online"); // TODO: 获取真实状态
                    conversations.add(conversation);
                }
            }
            
            // 获取群聊会话（基于群组成员关系）
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getUserId, userId)
                   .eq(ImGroupMember::getEnabled, 1)
                   .eq(ImGroupMember::getTenantId, "000000");
            
            List<ImGroupMember> memberships = imGroupMemberService.list(wrapper);
            for (ImGroupMember membership : memberships) {
                ImGroup group = imGroupService.getById(membership.getGroupId());
                if (group != null && "active".equals(group.getStatus())) {
                    // 获取群聊最后一条消息
                    List<ImMessage> groupMessages = imMessageService.getGroupMessageHistory(group.getGroupId(), 1, 1);
                    
                    // 计算群聊未读消息数
                    int unreadCount = imMessageService.getUnreadCount(userId, null, group.getGroupId());
                    
                    Map<String, Object> conversation = new HashMap<>();
                    conversation.put("id", group.getGroupId());
                    conversation.put("name", group.getGroupName());
                    conversation.put("avatar", group.getAvatar());
                    conversation.put("lastMessage", groupMessages.isEmpty() ? "群聊消息..." : groupMessages.get(0).getContent());
                    conversation.put("lastTime", groupMessages.isEmpty() ? group.getCreateTime() : groupMessages.get(0).getCreateTime());
                    conversation.put("unreadCount", unreadCount);
                    conversation.put("type", "group");
                    conversation.put("groupId", group.getGroupId());
                    conversation.put("memberCount", group.getMemberCount());
                    conversations.add(conversation);
                }
            }
            
            // 按最后消息时间排序
            conversations.sort((a, b) -> {
                Object timeA = a.get("lastTime");
                Object timeB = b.get("lastTime");
                if (timeA instanceof java.time.LocalDateTime && timeB instanceof java.time.LocalDateTime) {
                    return ((java.time.LocalDateTime) timeB).compareTo((java.time.LocalDateTime) timeA);
                }
                return 0;
            });
            
            log.info("获取会话列表成功: userId={}, 会话数量={}", userId, conversations.size());
            return R.ok(conversations);
        } catch (Exception e) {
            log.error("获取会话列表失败: {}", e.getMessage(), e);
            return R.fail("获取会话列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> markMessagesAsRead(Long userId, Long toUserId, String groupId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            int updatedCount = imMessageService.markAsRead(userId, toUserId, groupId);
            log.info("标记消息已读成功: userId={}, toUserId={}, groupId={}, 更新数量={}", 
                    userId, toUserId, groupId, updatedCount);
            return R.ok();
        } catch (Exception e) {
            log.error("标记消息已读失败: {}", e.getMessage(), e);
            return R.fail("标记消息已读失败: " + e.getMessage());
        }
    }

    @Override
    public R<Map<String, Object>> getGroupInfo(String groupId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("groupId", group.getGroupId());
            result.put("groupName", group.getGroupName());
            result.put("avatar", group.getAvatar());
            result.put("description", group.getDescription());
            result.put("ownerId", group.getOwnerId());
            result.put("groupType", group.getGroupType());
            result.put("maxMembers", group.getMaxMembers());
            result.put("memberCount", group.getMemberCount());
            result.put("status", group.getStatus());
            result.put("allowInvite", group.getAllowInvite());
            result.put("allowMemberModify", group.getAllowMemberModify());
            result.put("allowMemberInvite", group.getAllowMemberInvite());
            result.put("createTime", group.getCreateTime());
            result.put("updateTime", group.getUpdateTime());

            return R.ok(result);
        } catch (Exception e) {
            log.error("获取群聊详情失败: {}", e.getMessage(), e);
            return R.fail("获取群聊详情失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<Map<String, Object>>> getGroupMembers(String groupId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 查询群成员
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getGroupId, groupId)
                   .eq(ImGroupMember::getEnabled, 1)
                   .eq(ImGroupMember::getTenantId, "000000")
                   .orderByAsc(ImGroupMember::getRole, ImGroupMember::getJoinTime);
            
            List<ImGroupMember> members = imGroupMemberService.list(wrapper);
            
            List<Map<String, Object>> memberList = new ArrayList<>();
            for (ImGroupMember member : members) {
                // 获取用户信息
                SysUserVo user = imUserService.getSysUser(member.getUserId());
                
                Map<String, Object> memberInfo = new HashMap<>();
                memberInfo.put("userId", member.getUserId());
                memberInfo.put("role", member.getRole());
                memberInfo.put("groupNickname", member.getGroupNickname());
                memberInfo.put("joinTime", member.getJoinTime());
                memberInfo.put("isMuted", member.getIsMuted());
                memberInfo.put("enabled", member.getEnabled());
                
                if (user != null) {
                    // 用户信息存在，使用真实数据
                    memberInfo.put("userName", user.getUserName());
                    memberInfo.put("nickName", user.getNickName());
                    memberInfo.put("avatar", user.getAvatar());
                } else {
                    // 用户信息不存在，使用默认值
                    memberInfo.put("userName", "用户" + member.getUserId());
                    memberInfo.put("nickName", "用户" + member.getUserId());
                    memberInfo.put("avatar", "");
                    log.warn("用户信息不存在，使用默认值: userId={}", member.getUserId());
                }
                
                memberList.add(memberInfo);
            }

            return R.ok(memberList);
        } catch (Exception e) {
            log.error("获取群成员列表失败: {}", e.getMessage(), e);
            return R.fail("获取群成员列表失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> addGroupMembers(String groupId, Long operatorId, List<Long> memberIds) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 检查群组是否存在
            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            // 检查操作者权限
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getGroupId, groupId)
                   .eq(ImGroupMember::getUserId, operatorId)
                   .eq(ImGroupMember::getEnabled, 1);
            
            ImGroupMember operatorMember = imGroupMemberService.getOne(wrapper);
            if (operatorMember == null) {
                return R.fail("您不是群成员");
            }

            // 检查是否有邀请权限
            if (!"owner".equals(operatorMember.getRole()) && !"admin".equals(operatorMember.getRole())) {
                if (group.getAllowMemberInvite() == 0) {
                    return R.fail("您没有邀请权限");
                }
            }

            // 检查群组是否已满
            if (group.getMemberCount() + memberIds.size() > group.getMaxMembers()) {
                return R.fail("群组已满，无法添加更多成员");
            }

            // 添加成员
            int addedCount = 0;
            for (Long memberId : memberIds) {
                // 检查是否已经是成员
                LambdaQueryWrapper<ImGroupMember> memberWrapper = new LambdaQueryWrapper<>();
                memberWrapper.eq(ImGroupMember::getGroupId, groupId)
                            .eq(ImGroupMember::getUserId, memberId);
                
                ImGroupMember existingMember = imGroupMemberService.getOne(memberWrapper);
                if (existingMember == null) {
                    ImGroupMember member = new ImGroupMember();
                    member.setGroupId(groupId);
                    member.setUserId(memberId);
                    member.setGroupNickname("");
                    member.setRole("member");
                    member.setIsMuted(0);
                    member.setEnabled(1);
                    member.setTenantId("000000");
                    
                    imGroupMemberService.save(member);
                    addedCount++;
                }
            }

            // 更新群组成员数量
            group.setMemberCount(group.getMemberCount() + addedCount);
            imGroupService.updateById(group);

            // 发送群聊通知
            if (addedCount > 0) {
                String content = "添加了 " + addedCount + " 位新成员";
                sendGroupNotification(groupId, "member_added", content, operatorId);
            }

            log.info("添加群成员成功: groupId={}, operatorId={}, addedCount={}", groupId, operatorId, addedCount);
            return R.ok();
        } catch (Exception e) {
            log.error("添加群成员失败: {}", e.getMessage(), e);
            return R.fail("添加群成员失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> removeGroupMember(String groupId, Long operatorId, Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 检查群组是否存在
            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            // 检查操作者权限
            LambdaQueryWrapper<ImGroupMember> operatorWrapper = new LambdaQueryWrapper<>();
            operatorWrapper.eq(ImGroupMember::getGroupId, groupId)
                          .eq(ImGroupMember::getUserId, operatorId)
                          .eq(ImGroupMember::getEnabled, 1);
            
            ImGroupMember operatorMember = imGroupMemberService.getOne(operatorWrapper);
            if (operatorMember == null) {
                return R.fail("您不是群成员");
            }

            // 检查要移除的成员
            LambdaQueryWrapper<ImGroupMember> memberWrapper = new LambdaQueryWrapper<>();
            memberWrapper.eq(ImGroupMember::getGroupId, groupId)
                        .eq(ImGroupMember::getUserId, userId)
                        .eq(ImGroupMember::getEnabled, 1);
            
            ImGroupMember targetMember = imGroupMemberService.getOne(memberWrapper);
            if (targetMember == null) {
                return R.fail("该用户不是群成员");
            }

            // 检查权限：只有群主和管理员可以移除成员，或者自己退出
            if (!operatorId.equals(userId)) {
                if (!"owner".equals(operatorMember.getRole()) && !"admin".equals(operatorMember.getRole())) {
                    return R.fail("您没有移除成员的权限");
                }
                // 群主不能被移除
                if ("owner".equals(targetMember.getRole())) {
                    return R.fail("群主不能被移除");
                }
            }

            // 物理删除成员记录
            imGroupMemberService.removeById(targetMember.getId());

            // 更新群组成员数量
            group.setMemberCount(group.getMemberCount() - 1);
            imGroupService.updateById(group);

            // 发送群聊通知
            SysUserVo removedUser = imUserService.getSysUser(userId);
            String content = operatorId.equals(userId) ? 
                "退出了群聊" : 
                "移除了成员 " + (removedUser != null ? removedUser.getNickName() : "未知用户");
            sendGroupNotification(groupId, "member_removed", content, operatorId);

            log.info("移除群成员成功: groupId={}, operatorId={}, removedUserId={}", groupId, operatorId, userId);
            return R.ok();
        } catch (Exception e) {
            log.error("移除群成员失败: {}", e.getMessage(), e);
            return R.fail("移除群成员失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> updateGroupInfo(String groupId, Long operatorId, String groupName, String description, String avatar) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 检查群组是否存在
            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            // 检查操作者权限
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getGroupId, groupId)
                   .eq(ImGroupMember::getUserId, operatorId)
                   .eq(ImGroupMember::getEnabled, 1);
            
            ImGroupMember operatorMember = imGroupMemberService.getOne(wrapper);
            if (operatorMember == null) {
                return R.fail("您不是群成员");
            }

            // 检查修改权限：只有群主可以修改群信息
            if (!"owner".equals(operatorMember.getRole())) {
                if (group.getAllowMemberModify() == 0) {
                    return R.fail("您没有修改群信息的权限");
                }
            }

            // 更新群信息
            if (StringUtils.isNotBlank(groupName)) {
                group.setGroupName(groupName);
            }
            if (StringUtils.isNotBlank(description)) {
                group.setDescription(description);
            }
            if (StringUtils.isNotBlank(avatar)) {
                group.setAvatar(avatar);
            }

            imGroupService.updateById(group);

            // 发送群聊通知
            String content = "修改了群信息";
            sendGroupNotification(groupId, "group_info_updated", content, operatorId);

            log.info("更新群信息成功: groupId={}, operatorId={}", groupId, operatorId);
            return R.ok();
        } catch (Exception e) {
            log.error("更新群信息失败: {}", e.getMessage(), e);
            return R.fail("更新群信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> quitGroup(String groupId, Long userId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 检查群组是否存在
            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            // 检查用户是否是群成员
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getGroupId, groupId)
                   .eq(ImGroupMember::getUserId, userId)
                   .eq(ImGroupMember::getEnabled, 1);
            
            ImGroupMember member = imGroupMemberService.getOne(wrapper);
            if (member == null) {
                return R.fail("您不是群成员");
            }

            // 群主不能直接退出，需要先转让群主或解散群
            if ("owner".equals(member.getRole())) {
                return R.fail("群主不能直接退出，请先转让群主或解散群");
            }

            // 退出群聊
            member.setEnabled(0);
            imGroupMemberService.updateById(member);

            // 更新群组成员数量
            group.setMemberCount(group.getMemberCount() - 1);
            imGroupService.updateById(group);

            log.info("退出群聊成功: groupId={}, userId={}", groupId, userId);
            return R.ok();
        } catch (Exception e) {
            log.error("退出群聊失败: {}", e.getMessage(), e);
            return R.fail("退出群聊失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> disbandGroup(String groupId, Long operatorId) {
        try {
            if (!imProperties.isEnabled()) {
                return R.fail("IM功能未启用");
            }

            // 检查群组是否存在
            ImGroup group = imGroupService.getById(groupId);
            if (group == null) {
                return R.fail("群组不存在");
            }

            // 检查操作者是否是群主
            if (!operatorId.equals(group.getOwnerId())) {
                return R.fail("只有群主可以解散群聊");
            }

            // 解散群聊：将群状态设为解散
            group.setStatus("disbanded");
            imGroupService.updateById(group);

            // 禁用所有群成员
            LambdaQueryWrapper<ImGroupMember> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ImGroupMember::getGroupId, groupId)
                   .eq(ImGroupMember::getEnabled, 1);
            
            List<ImGroupMember> members = imGroupMemberService.list(wrapper);
            for (ImGroupMember member : members) {
                member.setEnabled(0);
                imGroupMemberService.updateById(member);
            }

            log.info("解散群聊成功: groupId={}, operatorId={}", groupId, operatorId);
            return R.ok();
        } catch (Exception e) {
            log.error("解散群聊失败: {}", e.getMessage(), e);
            return R.fail("解散群聊失败: " + e.getMessage());
        }
    }
}
